package com.jackrain.nea.fc.cp.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jackrain.nea.config.PropertiesConf;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.fc.cp.api.LdapConnectionCmd;
import com.jackrain.nea.sys.CommandAdapter;
import com.jackrain.nea.util.ApplicationContextHandle;
import com.jackrain.nea.util.ValueHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.HashMap;
import java.util.Hashtable;

/**
 * Created by ZCY on 2018/1/8.
 * ldap连接测试
 */
@Slf4j
@Component
@Service(protocol = "dubbo", validation = "true", version = "1.0", group = "cp")
public class LdapConnectionCmdImpl extends CommandAdapter implements LdapConnectionCmd {

    @Override
    public ValueHolder execute(HashMap map) throws NDSException {
        ValueHolder vh = new ValueHolder();
        JSONObject orgobj = new JSONObject(true);
        orgobj = orgldapload();
        vh.put("message", "组织连接成功");
        JSONObject userobj = new JSONObject(true);
        userobj = userldapload();
        JSONObject allobj = new JSONObject(true);
        allobj.put("org", orgobj);
        allobj.put("user", userobj);
        vh.put("data", allobj);
        vh.put("code", 0);
        return vh;

    }

    public JSONObject orgldapload() {
        JSONObject result = new JSONObject(true);
        DirContext ctx = null;
        Hashtable<String, String> env = new Hashtable<String, String>();
        try {

            PropertiesConf pconf = ApplicationContextHandle.getBean(PropertiesConf.class);
            String ldapurl = pconf.getProperty("ldap.urls");
            String adminName = pconf.getProperty("ad.ssl.admin");
            String adminpassword = pconf.getProperty("ad.ssl.password");
            String groupname = pconf.getProperty("ad.upper.organization");
            result.put("urls", ldapurl);
            result.put("admin", adminName);
            result.put("password", adminpassword);
            result.put("organization", groupname);

            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            env.put(Context.SECURITY_PRINCIPAL, adminName);
            env.put(Context.SECURITY_CREDENTIALS, adminpassword);
            env.put(Context.PROVIDER_URL, ldapurl);
        } catch (Exception e) {
            throw new NDSException("获取配置文件失败" + JSON.toJSONString(result), e);
        }

        try {
            ctx = new InitialDirContext(env);
            log.info("通过连接LDAP进行认证");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage() + "==无法通过LDAP认证===");
            throw new NDSException("登录的用户名或密码错误，无法通过LDAP认证:" + JSON.toJSONString(result)+"\\n"+e, e);
        }
        if (ctx != null) {
            closeCtx(ctx);
        }
        return result;
    }

    public JSONObject userldapload() {
        DirContext ctx = null;
        String groupname;
        Hashtable<String, String> env = new Hashtable<String, String>();
        String template;
        String disorgurl;
        JSONObject result = new JSONObject(true);
        try {
            PropertiesConf pconf = ApplicationContextHandle.getBean(PropertiesConf.class);
            String ldapurl = pconf.getProperty("ad.url");
            String adminName = pconf.getProperty("ad.ssl.admin");
            String adminpassword = pconf.getProperty("ad.ssl.password");
            groupname = pconf.getProperty("ad.upper.organization");
            disorgurl = pconf.getProperty("ad.disable.organization");
            template = pconf.getProperty("ad.path.template");
            String javaHome = System.getProperty("java.home");
            StringBuffer keystorebuf = new StringBuffer("");
            keystorebuf.append(System.getProperty("java.home"));
            keystorebuf.append(pconf.getProperty("ad.ssl.trustStore"));
            String storepassword = pconf.getProperty("ad.ssl.trustStorePassword");
            System.setProperty("javax.net.ssl.trustStore", keystorebuf.toString());
            System.setProperty("javax.net.ssl.trustStorePassword", storepassword);
            result.put("url", ldapurl);
            result.put("admin", adminName);
            result.put("password", adminpassword);
            result.put("organization", groupname);
            result.put("disable.organization",disorgurl);
            result.put("template", template);
            result.put("home", javaHome);
            result.put("trustStorePassword", storepassword);

            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            env.put(Context.SECURITY_PRINCIPAL, adminName);
            env.put(Context.SECURITY_CREDENTIALS, adminpassword);
            env.put(Context.SECURITY_PROTOCOL, "ssl");
            env.put(Context.PROVIDER_URL, ldapurl);

        } catch (Exception e) {
            throw new NDSException("获取配置文件失败" + JSON.toJSONString(result));
        }
        try {
            ctx = new InitialDirContext(env);
            log.info("用户连接通过连接LDAP进行认证\\n" + JSON.toJSONString(result));

        } catch (Exception e) {
            e.printStackTrace();
            log.error(e + "==无法通过LDAP认证===");
            throw new NDSException("登录的用户名或密码错误，无法通过LDAP认证"+e+"\\n"+JSON.toJSONString(result), e);
        }
        if (ctx != null) {
            closeCtx(ctx);
        }
        return result;
    }

    public static void closeCtx(DirContext ctx) {
        try {
            ctx.close();
        } catch (Exception ex) {
            log.error("=====关闭LDAP连接失败", ex);
        }
    }
}
